package com.zmn.plat.business.impl.base.fault;

import com.alibaba.fastjson.JSONArray;
import com.zmn.common.dto.VtDTO;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.plat.business.interfaces.base.fault.FaultBService;
import com.zmn.plat.common.dictionary.PlatErrorCodeDict;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.common.util.excel.ExcelImportUtil;
import com.zmn.plat.model.entity.base.acceptproject.AcceptProject;
import com.zmn.plat.model.entity.base.fault.Fault;
import com.zmn.plat.model.entity.base.maintainitem.MaintainItem;
import com.zmn.plat.model.entity.base.phenomenon.PhenomenonFault;
import com.zmn.plat.model.entity.base.phenomenon.PhenomenonFaultQuery;
import com.zmn.plat.model.entity.base.servicecontent.ServiceContent;
import com.zmn.plat.services.interfaces.base.acceptproject.AcceptProjectService;
import com.zmn.plat.services.interfaces.base.fault.FaultService;
import com.zmn.plat.services.interfaces.base.maintainitem.MaintainItemService;
import com.zmn.plat.services.interfaces.base.phenomenon.PhenomenonFaultService;
import com.zmn.plat.services.interfaces.base.phenomenon.PhenomenonService;
import com.zmn.plat.services.interfaces.base.servicecontent.ServiceContentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述: 故障业务实现类
 *
 * @author chengguang
 * @since 2021/11/25 17:51
 */
@Slf4j
@Service
public class FaultBServiceImpl implements FaultBService {
    @Resource
    private FaultService faultService;
    @Resource
    private PhenomenonFaultService phenomenonFaultService;
    @Resource
    private PhenomenonService phenomenonService;

    @Resource
    private MaintainItemService maintainItemService;

    @Resource
    private AcceptProjectService acceptProjectService;

    @Resource
    private ServiceContentService serviceContentService;

    @Override
    @Cacheable(cacheNames = "redis10m", key = "'base:listEfficientFaultByFaultPhenIds:faultPhenIds:'+#p0", unless = "#result == null")
    public List<Fault> listEfficientFaultByFaultPhenIds(List<Integer> faultPhenIds) {

        if (CollectionUtil.isNullOrEmpty(faultPhenIds)) {
            log.error("FaultBServiceImpl.listEfficientFaultByFaultPhenIds入参为空,faultPhenIds={}", faultPhenIds);
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL);
        }
        // 根据故障现象id 查询故障现象-具体故障关联
        List<PhenomenonFault> phenomenonFaults = phenomenonFaultService.listByQuery(PhenomenonFaultQuery.builder().phenIds(faultPhenIds).build());
        if (CollectionUtil.isNullOrEmpty(phenomenonFaults)) {
            return Collections.emptyList();
        }
        // 根据故障现象-具体故障关联获取全部具体故障ids
        List<Integer> faultIds = phenomenonFaults.stream().map(PhenomenonFault::getFaultId).distinct().collect(Collectors.toList());
        if (CollectionUtil.isNullOrEmpty(faultIds)) {
            return Collections.emptyList();
        }
        // 查询全部具体故障详情
        List<Fault> faults = faultService.listByIds(faultIds);
        return faults.stream().filter(e -> Objects.equals(GlobalConsts.YES, e.getStatus())).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateByKey(Fault fault) {

        if (StringUtil.isNotBlank(fault.getFaultName())) {
            // 修改关联表数据
            phenomenonFaultService.updateFaultNameByFaultId(fault.getFaultId(), fault.getFaultName());
        }
        faultService.updateByKey(fault);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatusBatch(List<Integer> faultIds, Integer status, String mcStaffRealName) {
//        if (GlobalConsts.NO == status) {
//            // 获取影响的故障现象id
//            List<Integer> phenIds = phenomenonFaultService.listByQuery(PhenomenonFaultQuery.builder()
//                    .faultIds(faultIds).build()).stream().map(PhenomenonFault::getPhenId).distinct().collect(Collectors.toList());
//            // 状态取消，删除故障现象关联的故障
//            phenomenonFaultService.deleteByFaultIds(faultIds);
//            for (Integer phenId : phenIds) {
//                List<PhenomenonFault> phenomenonFaults = phenomenonFaultService.listByQuery(PhenomenonFaultQuery.builder().phenId(phenId).build());
//                // 如果没有故障现象关联故障，关闭故障现象状态
//                if (CollectionUtil.isNullOrEmpty(phenomenonFaults)) {
//                    phenomenonService.updateByKey(Phenomenon.builder().phenId(phenId).status(GlobalConsts.NO).build());
//                }
//            }
//        }
//        faultService.updateStatusBatch(faultIds, status, mcStaffRealName);
        if (GlobalConsts.NO == status) {
            // 获取影响的故障现象id
            List<Integer> phenIds = phenomenonFaultService.listByQuery(PhenomenonFaultQuery.builder()
                    .faultIds(faultIds).build()).stream().map(PhenomenonFault::getPhenId).distinct().collect(Collectors.toList());
            // 状态取消，删除故障现象关联的故障
            phenomenonFaultService.deleteByFaultIds(faultIds);
            List<PhenomenonFault> phenomenonFaults = phenomenonFaultService.listByQuery(PhenomenonFaultQuery.builder().phenIds(phenIds).build());
            if (CollectionUtil.isNullOrEmpty(phenomenonFaults)) {
                phenomenonService.updateStatusBatch(phenIds,GlobalConsts.NO,mcStaffRealName);
            }else {
                // 根据现象id分组
                Map<Integer, List<PhenomenonFault>> phenomenonFaultsMap = phenomenonFaults.stream().collect(Collectors.groupingBy(PhenomenonFault::getPhenId));
                List<Integer> updateStatusPhenIds = new ArrayList<>();
                for (Integer phenId : phenIds) {
                    if (CollectionUtil.isNullOrEmpty(phenomenonFaultsMap.get(phenId))) {
                        updateStatusPhenIds.add(phenId);
                    }
                }
                if (CollectionUtil.isNotNullOrEmpty(updateStatusPhenIds)){
                    phenomenonService.updateStatusBatch(updateStatusPhenIds,GlobalConsts.NO,mcStaffRealName);
                }
            }
        }
        faultService.updateStatusBatch(faultIds, status, mcStaffRealName);
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO importTemplateFile(MultipartFile file) {
        long start = System.currentTimeMillis();
        try {
            InputStream inputStream = file.getInputStream();
            Workbook workbook = getWorkbook(inputStream, file.getOriginalFilename());
            Sheet sheetFault = ExcelImportUtil.getSheet(workbook, 2);
            Sheet sheetMaintainItem = ExcelImportUtil.getSheet(workbook, 3);
            Sheet sheetAcceptProject = ExcelImportUtil.getSheet(workbook, 4);
            Sheet sheetServiceContent = ExcelImportUtil.getSheet(workbook, 5);
            importFault(sheetFault);
            importMaintainItem(sheetMaintainItem);
            importAcceptProject(sheetAcceptProject);
            importServiceContent(sheetServiceContent);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseDTO.success(com.zmn.common.constant.GlobalConsts.SUCCESS_MSG, "耗时：" + (System.currentTimeMillis() - start));
    }


    public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {

        Workbook workbook = null;
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        if (".xls".equals(fileType)) {
            workbook = new HSSFWorkbook(inStr);
        } else if (".xlsx".equals(fileType)) {
            workbook = new XSSFWorkbook(inStr);
        } else {
            throw new Exception("请上传excel文件！");
        }
        return workbook;
    }

    private void importServiceContent(Sheet sheetServiceContent) {
        List<String[]> oList = ExcelImportUtil.listFromSheet(sheetServiceContent);
        if (CollectionUtil.isNotNullOrEmpty(oList)) {
            List<ServiceContent> serviceContentList = new ArrayList<>();
            for (int s = 1; s < oList.size(); s++) {
                String[] rows = oList.get(s).clone();
                Integer id = null;
                try {
                    id = Integer.parseInt(rows[3]);
                    serviceContentList.add(ServiceContent.builder()
                            .servId(id)
                            .servDesc(rows[2])
                            .servCharge("是".equals(rows[4]) ? 2 : 1)
                            .status(replaceStatus(rows[5]))
                            .sort(Integer.parseInt(rows[6]))
                            .updateTime(DateUtil.getNow())
                            .createTime(DateUtil.getNow())
                            .creater("system")
                            .updater("system")
                            .build());
                } catch (Exception e) {
                }
            }
            serviceContentService.insertBatchExport(serviceContentList);
        }
    }

    private void importAcceptProject(Sheet sheetAcceptProject) {
        List<String[]> oList = ExcelImportUtil.listFromSheet(sheetAcceptProject);
        if (CollectionUtil.isNotNullOrEmpty(oList)) {
            List<AcceptProject> acceptProjectList = new ArrayList<>();
            for (int s = 1; s < oList.size(); s++) {
                String[] rows = oList.get(s).clone();
                String selectValue = replaceSelectValue(
                        rows[6], "是".equals(rows[7]),
                        rows[8], "是".equals(rows[9]),
                        rows[10], "是".equals(rows[11]));
                Integer id = null;
                try {
                    id = Integer.parseInt(rows[4]);
                    acceptProjectList.add(AcceptProject.builder()
                            .acceId(id)
                            .acceName(rows[3])
                            .acceType("工程师验收项目".contains(rows[2]) ? 1 : 2)
                            .referenceValue(rows[5])
                            .selectValue(selectValue)
                            .status(replaceStatus(rows[12]))
                            .sort(Integer.parseInt(rows[13]))
                            .updateTime(DateUtil.getNow())
                            .createTime(DateUtil.getNow())
                            .creater("system")
                            .updater("system")
                            .build());
                } catch (Exception e) {
                }
            }
            acceptProjectService.insertBatchExport(acceptProjectList);
        }
    }

    private void importFault(Sheet sheetFault) {
        List<String[]> oList = ExcelImportUtil.listFromSheet(sheetFault);
        if (CollectionUtil.isNotNullOrEmpty(oList)) {
            List<Fault> faultList = new ArrayList<>();
            for (int s = 1; s < oList.size(); s++) {
                String[] rows = oList.get(s).clone();
                Integer id = null;
                try {
                    id = Integer.parseInt(rows[4]);
                    faultList.add(Fault.builder()
                            .faultId(id)
                            .faultName(rows[3])
                            .faultLevel(replaceFaultLevel(rows[5]))
                            .faultDesc(rows[6])
                            .status(replaceStatus(rows[7]))
                            .sort(Integer.parseInt(rows[8]))
                            .updateTime(DateUtil.getNow())
                            .createTime(DateUtil.getNow())
                            .creater("system")
                            .updater("system").build());
                } catch (Exception e) {
                }
            }
            // 写入故障数据
            faultService.insertBatchExport(faultList);
        }
    }

    private void importMaintainItem(Sheet sheetMaintainItem) {
        List<String[]> oList = ExcelImportUtil.listFromSheet(sheetMaintainItem);
        if (CollectionUtil.isNotNullOrEmpty(oList)) {
            List<MaintainItem> maintainItemList = new ArrayList<>();
            for (int s = 1; s < oList.size(); s++) {
                String[] rows = oList.get(s).clone();
                String selectValue = replaceSelectValue(
                        rows[9], "是".equals(rows[10]),
                        rows[11], "是".equals(rows[12]),
                        rows[13], "是".equals(rows[14]));
                Integer id = null;
                try {
                    id = Integer.parseInt(rows[6]);
                    maintainItemList.add(MaintainItem.builder()
                            .maintainName(rows[5])
                            .maintainId(id)
                            .isCheck("是".equals(rows[7]) ? 2 : 1)
                            .referenceValue(rows[8])
                            .selectValue(selectValue)
                            .status(replaceStatus(rows[15]))
                            .sort(Integer.parseInt(rows[16]))
                            .updateTime(DateUtil.getNow())
                            .createTime(DateUtil.getNow())
                            .creater("system")
                            .updater("system").build());
                } catch (Exception e) {
                }
            }
            // 写入检修项目数据
            maintainItemService.insertBatchExport(maintainItemList);
        }
    }

    private String replaceSelectValue(String selectValue1, Boolean selectValue1IsDefault,
                                      String selectValue2, Boolean selectValue2IsDefault,
                                      String selectValue3, Boolean selectValue3IsDefault) {
        List<VtDTO> selectValueList = new ArrayList<>();
        selectValueList.add(new VtDTO(1, selectValue1, selectValue1IsDefault));
        selectValueList.add(new VtDTO(2, selectValue2, selectValue2IsDefault));
        if (StringUtil.isNotBlank(selectValue3)) {
            selectValueList.add(new VtDTO(3, selectValue3, selectValue3IsDefault));
        }
        return CollectionUtil.isNotNullOrEmpty(selectValueList) ? JSONArray.toJSONString(selectValueList) : "";
    }

    private Integer replaceStatus(String row) {
        if ("启用".equals(row)) {
            return 2;
        }
        return 1;
    }

    private Integer replaceFaultLevel(String row) {
        // 1简单 2一般 3复杂 4严重
        if ("简单故障".equals(row)) {
            return 1;
        }
        if ("一般故障".equals(row)) {
            return 2;
        }
        if ("复杂故障".equals(row)) {
            return 3;
        }
        if ("严重故障".equals(row)) {
            return 4;
        }
        return null;
    }
}
